#include <iostream>
#include <string>
#include <vector>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
#include "task.hpp"


#define PROCESSNUM 6
#define TASKNUM 6

using std::string;
using std::vector;

vector<task_t> task;

struct process{
    int _cmdFd;
    pid_t _childPid;
    string _childName;

    process(const int& cmdFd, const pid_t& childPid, const string& childName)
        :_cmdFd(cmdFd)
        ,_childPid(childPid)
        ,_childName(childName)
    {}
};

void execute(){
    while(1){
        sleep(1);
        int cmdcode = 0;
        int n = read(0, &cmdcode, sizeof(cmdcode));
        if(n == sizeof(cmdcode)){
            // cout<<"task"<<cmdcode<<endl;
            task[cmdcode]();
        }
        else if(n == 0) {
            // cout<<"fork before"<<endl;
            break;
        }
    }
}

void ctrlchild(const vector<process>& pool){
    while(1){
        // 选择任务
        int cmdcode = rand() % TASKNUM; 
        // 选择进程
        int processcode = rand() % PROCESSNUM;
        // 发送任务
        write(pool[processcode]._cmdFd, &cmdcode, sizeof(cmdcode));
    }
}

void initprocessPool(vector<process>* pool){
    loadTask(&task);
    for(int i = 0; i < PROCESSNUM; ++i){
        int pipefd[2];
        int n = pipe(pipefd);
        // cout<<"fork before"<<endl;
        pid_t id = fork();
        if(id < 0){
            perror("fork");
            // cout<<"forkerror"<<endl;
        }
        else if(id == 0){
            close(pipefd[1]);

            dup2(pipefd[0], 0);
            close(pipefd[0]);
            // 执行任务
            // cout<<"execute();"<<endl;
            execute();
            exit(0);
        }
        close(pipefd[0]);

        // 添加描述管理
        string name = "processName_" + i;
        pool->push_back(process(pipefd[1], id, name));
    }
}

void quitprocess(const vector<process>& pool){
    for(auto& it : pool) close(it._cmdFd);
    for(auto& it : pool) waitpid(it._childPid, nullptr, 0);
}

int main(){
    srand(time(nullptr)*getpid());
    vector<process> pool;
    // 初始化
    initprocessPool(&pool);
    
    // 控制子进程
    ctrlchild(pool);

    // 回收
    quitprocess(pool);

    return 0;
}